﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Extensions;
using Abp.Runtime.Session;
using Abp.UI;
using Mt.Site.Application.Dto;
using Mt.Site.Application.StaticPages.Dto;
using Mt.Site.Core.Authorization;
using Mt.Site.Core.Base.Utils.FileIO;
using Mt.Site.Core.Base.Utils.FileIO.Encode;
using Mt.Site.Core.MultiTenancy;
using Mt.Site.Core.StaticPages;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Linq.Dynamic.Core;

namespace Mt.Site.Application.StaticPages
{
    public class StaticPageAppService: MtSiteAppServiceBase,IStaticPageAppService
    {
        private readonly IAppFolders _appFolders;
        private readonly IEncodeHelper _encodeHelper;
        private readonly IStaticPageSettingManager _staticPageSettingManager;

        private readonly IStaticPageManager _staticPageManager;

        public StaticPageAppService(
                IAppFolders appFolders,
                IEncodeHelper encodeHelper,
                IStaticPageSettingManager staticPageSettingManager,
                IStaticPageManager staticPageManager)
        {
            _appFolders = appFolders;
            _encodeHelper = encodeHelper;
            _staticPageSettingManager = staticPageSettingManager;
            _staticPageManager = staticPageManager;
        }
        [AbpAuthorize(AppPermissions.Pages_StaticPages)]
        public PagedResultDto<StaicPageItem> GetPageFiles(GetStaticPathPagesInput input)
        {
            var path = FilterPath(input.Path);

            if (!Directory.Exists(path))
            {
                return null;
            }

            if (!CheckPathVaild(new List<string> { input.Path }))
            {
                return null;
            }
            

            DirectoryInfo dirInfo = new DirectoryInfo(path);
            List<FileSystemInfo> fileInfos = null;
            if (!input.Filter.IsNullOrWhiteSpace())
            {
                fileInfos = dirInfo.GetFileSystemInfos("*"+ input.Filter + "*").ToList();
            }
            else
            {
                fileInfos = dirInfo.GetFileSystemInfos().ToList();
            }
            //if (!input.Sorting.IsNullOrWhiteSpace())
            //{
            //    fileInfos = fileInfos.OrderByDynamic(input.Sorting).ToList();
            //}
            if (path.Equals(_appFolders.StaticPageFolder))
            {
                if (AbpSession.TenantId != null)
                {
                    var tenant = GetCurrentTenant();
                    fileInfos = fileInfos.FindAll(item => { return item.Name == tenant.TenancyName; });
                }
               
            }
            var count = fileInfos.Count();
            var list = fileInfos.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();

            var result = new List<StaicPageItem>();
            var deviceType = DeviceType.Pc;
            foreach (var item in list)
            {
                var _path = GetReleativePath(item.FullName);
                var temp = new StaicPageItem
                {
                    CreationTime = item.CreationTime,
                    IsDirectory = item is DirectoryInfo,
                    Name = item.Name,
                    Path = _path
                };

                if (!temp.IsDirectory)
                {
                    temp.FrontUrl = _staticPageManager.GetVisitUrl(_path, out deviceType);
                }
                result.Add(temp);

            }
            return new PagedResultDto<StaicPageItem>(count, result);
        }

        [AbpAuthorize(AppPermissions.Pages_StaticPages_Delete)]
        public void DeleteStaticPages(DeleteStaicPagesInput input)
        {
            if (!CheckPathVaild(input.Paths, false))
            {
                return;
            }

            foreach (var item in input.Paths)
            {
                try
                {
                    var path = Path.Combine(_appFolders.StaticPageFolder, item);
                    if (Directory.Exists(path))
                    {
                        FileHelper.DeleteFolderIfExists(path);
                    }
                    else
                    {
                        FileHelper.DeleteFileIfExists(path);
                    }
                }
                catch (IOException)
                {
                    throw new UserFriendlyException(L("DeleteFilePathFailure", item));
                }
            }
        }

        [AbpAuthorize(AppPermissions.Pages_StaticPages_Settings)]
        public async Task CreateOrUpdateStaticPageConfig(ConfigFileDto input)
        {
            await _staticPageSettingManager.CreateOrUpdateStaticPageConfig(input.Content);
        }

        [AbpAuthorize(AppPermissions.Pages_StaticPages_Settings)]
        public async Task<string> GetStaticPageConfig()
        {
            return await _staticPageSettingManager.GetConfigFileContentAsync();
        }

        [AbpAuthorize(AppPermissions.Pages_StaticPages_Build)]
        public async Task GenerateWholeSitePages()
        {
            await _staticPageManager.GenerateWholeSitePages(AbpSession.TenantId, AbpSession.CultureName());
        }
        [AbpAuthorize(AppPermissions.Pages_StaticPages_Build)]
        public void GeneratePageByPath(string path)
        {
            _staticPageManager.GeneratePagesByPath(path);
        }
        [AbpAuthorize(AppPermissions.Pages_StaticPages_Build)]
        public async Task VisitPage(string path)
        {
            await _staticPageManager.VisitPage(path);
        }
        [AbpAuthorize(AppPermissions.Pages_StaticPages_Build)]
        public async Task<GeneratePagesOut> GetGeneratePagesResult()
        {
            var result = await _staticPageManager.GetGenerateResult(AbpSession.TenantId, AbpSession.CultureName());
            return new GeneratePagesOut
            {
                Generating = result.Generating,
                GenratedSuccussfully = result.GenratedSuccussfully,
                ToBeGenerated = result.ToBeGenerated
            };
        }


        public async Task ResetMobileStatiPageDataAsync()
        {
            await _staticPageManager.ResetMobileStatiPageDataAsync();
        }

        private string GetReleativePath(string Path)
        {
            if (!Path.IsNullOrWhiteSpace())
            {
                var len = _appFolders.StaticPageFolder.Length +1;
                if (Path.Length <= len)
                {
                    return "";
                }
                string _path = Path.Substring(len, Path.Length - len).Replace('\\','/');
                return _path;
            }
            return "";
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="paths"></param>
        /// <param name="isPathEmptyAble">路径是否可空</param>
        /// <returns></returns>
        private bool CheckPathVaild(List<string> paths, bool isPathEmptyAble = true)
        {
            var isVaild = true;
            var tenantId = AbpSession.TenantId;
            Tenant tenant = null;
            if (tenantId != null)
            {
                tenant = GetCurrentTenant();
            }
            foreach (var item in paths)
            {
                if (!isPathEmptyAble && item.IsNullOrWhiteSpace())
                {
                    isVaild = false;
                    break;
                }
                if (!item.IsNullOrEmpty() && tenant != null)
                {
                    if (!item.StartsWith(tenant.TenancyName))
                    {
                        isVaild = false;
                        break;
                    }

                }
            }
            return isVaild;
            
        }


        private  string FilterPath(string path)
        {
            if (path.IsNullOrWhiteSpace())
            {
                return _appFolders.StaticPageFolder;
            }
            var systemSeparatorChar = Path.DirectorySeparatorChar.ToString();
            var temp = path.Replace("/", systemSeparatorChar).Replace("//", systemSeparatorChar).Replace(".." + systemSeparatorChar, "");
            temp = Path.Combine(_appFolders.StaticPageFolder, temp);
            return temp;
        }
    }
}
